<template>
  <div class="input-number-editor" :class="{'has-error': hasError}">
    <input ref="input" :value="internalValue" :maxlength="maxlength" @input="onInput" class="input">
    <span v-if="showClearIcon" class="icon" title="清除" @click="clear">
      <svg-icon name="close"></svg-icon>
    </span>
    <span v-if="showRestoreIcon" class="icon" title="撤销" @click="restore">
      <svg-icon name="return"></svg-icon>
    </span>
    <span v-if="showUpdateIcon" class="icon" title="确定" @click="update">
      <svg-icon name="seleted"></svg-icon>
    </span>
  </div>
</template>

<script>
export default {
  name: 'input-number-editor',
  props: {
    maxlength: {
      type: [Number, String],
      default: 6,
    },
    value: [String, Number],
    showUpdateIcon: {
      type: Boolean,
      default: true,
    },
    showClearIcon: {
      type: Boolean,
      default: true,
    },
    showRestoreIcon: {
      type: Boolean,
      default: true,
    },
    autoFocus: {
      type: Boolean,
      default: true,
    },
  },
  data () {
    return {
      internalValue: this.formatValue(this.value),
    }
  },
  computed: {
    hasError () {
      const value = this.internalValue
      return this.autoFocus && (value === '' || value == null)
    },
  },
  mounted () {
    const input = this.$refs.input
    input.value = this.internalValue
    if (this.autoFocus) {
      input.focus()
      input.select()
    }
  },
  methods: {
    formatValue (value) {
      value = String(value)
      // 去掉首尾空格
      value = value.trim()
      // 先把非数字的都替换掉，除了数字和.
      value = value.replace(/[^0-9.]/g, '');
      // 必须保证第一个为数字而不是.
      value = value.replace(/^\./g, '');
      // 保证只有出现一个.而没有多个.
      value = value.replace(/\.{2,}/g, '.');
      // 保证.只出现一次，而不能出现两次以上
      value = value.replace('.', '$#$')
        .replace(/\./g, '')
        .replace('$#$', '.')
      return value
    },
    onInput (evt) {
      const value = this.formatValue(evt.target.value)
      this.$refs.input.value = value
      this.internalValue = value
      this.$emit('input', this.internalValue)
    },
    focus () {
      this.$refs.input.focus()
    },
    blur () {
      this.$refs.input.blur()
    },
    clear () {
      this.internalValue = ''
      this.$refs.input.value = ''
      this.$nextTick(() => {
        this.focus()
      })
    },
    restore () {
      this.internalValue = this.formatValue(this.value)
      this.$refs.input.value = this.internalValue
      this.$nextTick(() => {
        this.focus()
      })
    },
    update () {
      this.$emit('update', { value: this.internalValue, input: this.$refs.input })
    },
  },
}
</script>

<style lang="scss" scoped>
.input-number-editor {
  display: inline-flex;
  align-items: center;
  border: 1px solid #ddd;
  border-radius: 4px;
  overflow: hidden;
  background: white;
  &.has-error {
    border-color: red;
  }

  .input {
    -webkit-appearance: none;
    appearance: none;
    border: none;
    outline: none;
    padding-left: 10px;
    padding-right: 10px;
    background: transparent;
  }

  .icon {
    font-size: 16px;
    color: #ccc;
    display: inline-block;
    width: 22px;
    height: 28px;
    text-align: center;
    line-height: 28px;
    transition: all .3s;

    &:hover {
      color: #333333;
    }
  }
}
</style>
